package com.icost.directive.config;

import com.icost.directive.entity.AccessLog;
import com.icost.directive.repository.AccessLogRepository;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

@Component
public class AccessLogFilter implements Filter {

    private final AccessLogRepository accessLogRepository;

    // 需要记录日志的 URL 前缀（可配置）
    private final List<String> includedPrefixes = List.of("/api", "/admin");

    public AccessLogFilter(AccessLogRepository accessLogRepository) {
        this.accessLogRepository = accessLogRepository;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {


        String uri = ((HttpServletRequest) request).getRequestURI();
        boolean shouldLog = includedPrefixes.stream().anyMatch(uri::startsWith);

        long start = System.currentTimeMillis();

        if (uri.startsWith("/h2-console") || !uri.startsWith("/api")) {
            chain.doFilter(request, response);
        } else {
            CachedBodyHttpServletRequest wrappedRequest = new CachedBodyHttpServletRequest((HttpServletRequest) request);
            CachedBodyHttpServletResponse wrappedResponse = new CachedBodyHttpServletResponse((HttpServletResponse) response);

            chain.doFilter(wrappedRequest, wrappedResponse);
            if (shouldLog) {
                long duration = System.currentTimeMillis() - start;

                AccessLog log = new AccessLog();
                log.setMethod(wrappedRequest.getMethod());
                log.setUri(uri);
                log.setParams(wrappedRequest.getQueryString());
                log.setClientIp(wrappedRequest.getRemoteAddr());
                log.setStatus(wrappedResponse.getStatus());
                log.setDuration(duration);

                // 请求体（最多 2KB）
                String body = wrappedRequest.getCachedBodyAsString();
                if (body.length() > 2048) {
                    body = body.substring(0, 2048) + "...(truncated)";
                }
                log.setRequestBody(body);

                // 响应体（最多 2KB）
                String respBody = wrappedResponse.getCachedBodyAsString();
                if (respBody.length() > 2048) {
                    respBody = respBody.substring(0, 2048) + "...(truncated)";
                }
                log.setResponseBody(respBody);

                accessLogRepository.save(log);
            }
        }
        //  chain.doFilter(wrappedRequest, wrappedResponse);

    }
}
